/**
 * @file
 * @brief 算法IPC通信框架
 * @note 算法清单文件
 * 示例
 * ```
 * -
 *   name: "Test1"
 *   ipaddr: "127.0.0.1"
 *   port: 14010
 * -
 *   name: "Test2"
 *   ipaddr: "127.0.0.1"
 *   port: 14011
 *
 * ```
 * 算法调用原理：
 * 1. 注册funcGetData和funcSendResult
 * 2. 调用Boot启动IPC处理流程
 * 3. 当Client没有图像需要处理时，调用funcGetData获取图片
 * 4. 图片将提交到算法处理，等待处理完成
 * 5. 当处理完成后将调用funcSendResult，传出结果
 * @note
 * 数据将会复制一份到Thrift Client线程中
 */

#ifndef ALGORITHM_IPC_H
#define ALGORITHM_IPC_H

#include "BufferImage.hpp"
#include <Algorithm.h>
#include <BufferImage.hpp>
#include <NodeClient.h>
#include <deque>
#include <functional>
#include <memory>
#include <pthread.h>
#include <thread>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransport.h>

struct ClientPara {
  std::string name;
  std::string ipaddr;
  long port;
};

class AlgorithmManager {
private:
  class ClientObject {
  private:
    std::shared_ptr<apache::thrift::transport::TTransport> socket;
    std::shared_ptr<apache::thrift::transport::TTransport> transport;
    std::shared_ptr<apache::thrift::protocol::TProtocol> protocol;
    AlgorithmIPC::AlgorithmClient *client;
    std::jthread workThread;
    std::string name;
    pthread_t currentThread;

  public:
    ClientObject(const std::string &name, const std::string &ipaddr, long port);
    virtual ~ClientObject();
    std::function<BufferImage()> funcGet;
    std::function<void(std::string, std::string)> funcSet;
  };
  std::deque<ClientObject> clientList;

public:
  AlgorithmManager();
  virtual ~AlgorithmManager();
  void Boot(const std::deque<ClientPara> &clientList);
  std::function<BufferImage()> funcGetData;
  std::function<void(std::string, std::string)> funcSendResult;
};

#endif
